package com.rxh.controller;

import com.rxh.pojo.merchant.*;
import com.rxh.pojo.payment.TradeObject;
import com.rxh.service.MerchantService;
import com.rxh.service.MerchantUserService;
import com.rxh.spring.annotation.SystemLogInfo;
import com.rxh.util.QuickTestUtils;
import com.rxh.util.UserInfoUtils;
import com.rxh.utils.GlobalConfiguration;
import com.rxh.utils.HttpClientUtils;
import com.rxh.utils.SystemConstant;
import org.apache.commons.io.IOUtils;
import org.springframework.http.CacheControl;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 * User: 陈俊雄
 * Date: 2018/3/21
 * Time: 14:51
 * Project: Management
 * Package: com.rxh.controller
 */
@Controller
@RequestMapping(value = "/merchant")
public class MerchantController {
    @Resource
    private MerchantService merchantService;

    @Resource
    private MerchantUserService merchantUserService;

    @Resource
    private BCryptPasswordEncoder passwordEncoder;

    @Resource
    private GlobalConfiguration globalConfiguration;

    @RequestMapping(value = "/isMerchantIdExist")
    @ResponseBody
    public Boolean isMerchantIdExist(@RequestBody Integer merId) {
        return merchantService.isMerchantIdExist(merId);
    }

    /**
     * 新增商户：包含：MerchantInfo/MerchantSetting/MerchantPay
     *
     * @param merchant 商户对象
     * @return 是否成功
     */
    @SystemLogInfo(description = "新增商户")
    @RequestMapping(value = "/addMerchant")
    @ResponseBody
    public Boolean addMerchant(@RequestBody Merchant merchant) {
        return merchantService.addMerchant(merchant, UserInfoUtils.getName());
    }

    @SystemLogInfo(description = "删除商户")
    @RequestMapping(value = "/deleteMerchantById")
    @ResponseBody
    public Boolean deleteMerchant(@RequestBody Integer merchantId) {
        return merchantService.deleteMerchantById(merchantId);
    }

    /**
     * 更新商户：
     *
     * @param merchant 商户对象 包含：MerchantInfo/MerchantSetting/MerchantPay
     * @return 是否成功
     */
    @SystemLogInfo(description = "更新商户")
    @RequestMapping(value = "/updateMerchant")
    @ResponseBody
    public Boolean updateMerchant(@RequestBody Merchant merchant) {
        return merchantService.updateMerchant(merchant, UserInfoUtils.getName());
    }

    @SystemLogInfo(description = "新增商户信息")
    @RequestMapping(value = "/addMerchantInfo")
    @ResponseBody
    public Boolean addMerchantInfo(@RequestBody MerchantInfo merchantInfo) {
        return merchantService.addMerchantInfo(merchantInfo, UserInfoUtils.getName());
    }

    @RequestMapping(value = "/uploadMerchantCertificate")
    @ResponseBody
    public String uploadMerchantCertificate(@RequestParam("file") MultipartFile multipartFiles, @RequestParam("merchantId") Integer merchantId) throws IOException {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        String certificatePath = globalConfiguration.getFileUploadPath() + merchantId + "/";
        File filePath = new File(certificatePath);
        if (!filePath.exists()) {
            filePath.mkdir();
        }
        certificatePath += dateFormat.format(new Date()) + multipartFiles.getOriginalFilename().substring(multipartFiles.getOriginalFilename().indexOf("."));
        File file = new File(certificatePath);
        multipartFiles.transferTo(file);
        return certificatePath.replace(globalConfiguration.getFileUploadPath(), "");
    }

    @SystemLogInfo(description = "删除商户信息")
    @RequestMapping(value = "/deleteMerchantInfo")
    @ResponseBody
    public Boolean deleteMerchantInfo(@RequestBody MerchantInfo merchantInfo) {
        return merchantService.deleteMerchantInfo(merchantInfo);
    }

    @SystemLogInfo(description = "更新商户信息")
    @RequestMapping(value = "/updateMerchantInfo")
    @ResponseBody
    public Boolean updateMerchantInfo(@RequestBody MerchantInfo merchantInfo) {
        return merchantService.updateMerchantInfo(merchantInfo, UserInfoUtils.getName());
    }

    @RequestMapping(value = "/getMerchantSettingInit")
    @ResponseBody
    public Map<String, Object> getMerchantSettingInit() {
        return merchantService.getMerchantSettingInit();
    }

    @SystemLogInfo(description = "新增商户设置")
    @RequestMapping(value = "/addMerchantSetting")
    @ResponseBody
    public Boolean addMerchantSetting(@RequestBody MerchantSetting merchantSetting) {
        return merchantService.addMerchantSetting(merchantSetting);
    }

    @SystemLogInfo(description = "删除商户设置")
    @RequestMapping(value = "/deleteMerchantSetting")
    @ResponseBody
    public Boolean deleteMerchantSetting(@RequestBody MerchantSetting merchantSetting) {
        return merchantService.deleteMerchantSetting(merchantSetting);
    }

    @SystemLogInfo(description = "更新商户设置")
    @RequestMapping(value = "/updateMerchantSetting")
    @ResponseBody
    public Boolean updateMerchantSetting(@RequestBody MerchantSetting merchantSetting) {
        return merchantService.updateMerchantSetting(merchantSetting, UserInfoUtils.getName());
    }

    @SystemLogInfo(description = "新增商户支付属性")
    @RequestMapping(value = "/addMerchantPay")
    @ResponseBody
    public Boolean addMerchantPay(@RequestBody MerchantPay merchantPay) {
        return merchantService.addMerchantPay(merchantPay);
    }

    @SystemLogInfo(description = "删除商户支付属性")
    @RequestMapping(value = "/deleteMerchantPay")
    @ResponseBody
    public Boolean deleteMerchantPay(@RequestBody MerchantPay merchantPay) {
        return merchantService.deleteMerchantPay(merchantPay);
    }

    @SystemLogInfo(description = "更新商户支付属性")
    @RequestMapping(value = "/updateMerchantPay")
    @ResponseBody
    public Boolean updateMerchantPay(@RequestBody MerchantPay merchantPay) {
        return merchantService.updateMerchantPay(merchantPay, UserInfoUtils.getName());
    }

    @RequestMapping(value = "/getMerchantPayInit")
    @ResponseBody
    public Map<String, Object> getMerchantPayInit() {
        return merchantService.getMerchantPayInit();
    }

    @RequestMapping(value = "/getMerchantPayByWebSiteId")
    @ResponseBody
    public MerchantPay getMerchantPayByWebSiteId(@RequestBody Integer webSiteId) {
        return merchantService.selectMerchantPayByRefIdAndRefType(webSiteId, SystemConstant.REF_TYPE_WEB);
    }

    @RequestMapping(value = "/getMgmtInit")
    @ResponseBody
    public Map<String, Object> getMgmtInit() {
        return merchantService.getMgmtInit();
    }

    @SystemLogInfo(description = "批量更新商户扣率")
    @RequestMapping(value = "/updateMerchantRateByList")
    @ResponseBody
    public Boolean updateMerchantRateByList(@RequestBody List<MerchantRate> merchantRateList) {
        return merchantService.updateMerchantRateByList(merchantRateList, UserInfoUtils.getName());
    }

    @SystemLogInfo(description = "获取商户汇率")
    @RequestMapping(value = "/getMerchantRateByRefIdAndRefType")
    @ResponseBody
    public List<MerchantRate> getMerchantRateByRefIdAndRefType(@RequestBody MerchantRate merchantRate) {
        return merchantService.getMerchantRateByRefIdAndRefType(merchantRate.getRefId(), merchantRate.getRefType());
    }

    @RequestMapping(value = "/isMerchantUserExist")
    @ResponseBody
    public Boolean isMerchantUserExist(@RequestBody MerchantUser merchantUser) {
        return merchantUserService.isUserExist(merchantUser);
    }

    @SystemLogInfo(description = "新增商户用户")
    @RequestMapping(value = "/addMerchantUser")
    @ResponseBody
    public Boolean addMerchantUser(@RequestBody MerchantUser merchantUser) {
        merchantUser.setPassword(passwordEncoder.encode(merchantUser.getPassword()));
        return merchantUserService.addUser(merchantUser, UserInfoUtils.getName());
    }

    @SystemLogInfo(description = "删除商户用户")
    @RequestMapping(value = "/deleteMerchantUser")
    @ResponseBody
    public Boolean deleteMerchantUser(@RequestBody List<Long> idList) {
        return merchantUserService.deleteUserByIdList(idList);
    }

    @SystemLogInfo(description = "更新商户用户")
    @RequestMapping(value = "/updateMerchantUser")
    @ResponseBody
    public Boolean updateMerchantUser(@RequestBody MerchantUser merchantUser) {
        if (merchantUser.getPassword() != null) {
            merchantUser.setPassword(passwordEncoder.encode(merchantUser.getPassword()));
        }
        return merchantUserService.updateUserById(merchantUser, UserInfoUtils.getName());
    }

    @SystemLogInfo(description = "获取商户用户")
    @RequestMapping(value = "/getMerchantUserByMerchantId")
    @ResponseBody
    public List<MerchantUser> getMerchantUserByMerchantId(@RequestBody Integer merchantId) {
        return merchantUserService.getUserByMerchantId(merchantId);
    }

    @SystemLogInfo(description = "获取商户列表")
    @RequestMapping(value = "/getAllMerchantInfoForView")
    @ResponseBody
    public Map<String, Object> getAllMerchantInfoForView() {
        return merchantService.getAllMerchantInfoForView();
    }

    @RequestMapping(value = "/webSite/getInit")
    @ResponseBody
    public Map<String, Object> getWebSiteInit() {
        return merchantService.getWebSiteInit();
    }

    @SystemLogInfo(description = "获取商户网址列表")
    @RequestMapping(value = "/getAllMerchantWebSite")
    @ResponseBody
    public List<MerchantWebSite> getAllMerchantWebSite() {
        return merchantService.selectAllMerchantWebSite();
    }

    /**
     * 商户网址是否存在
     *
     * @param siteUrl 商户网址
     * @return true/false
     */
    @RequestMapping(value = "/webSite/isExist")
    @ResponseBody
    public Boolean isSiteUrlExist(@RequestBody String siteUrl) {
        return merchantService.isSiteUrlExist(siteUrl);
    }

    @SystemLogInfo(description = "添加商户网址")
    @RequestMapping(value = "/webSite/add")
    @ResponseBody
    public Boolean addMerchantWebSite(@RequestBody MerchantWebSite merchantWebSite) {
        return merchantService.addMerchantWebSite(merchantWebSite, UserInfoUtils.getName());
    }

    @SystemLogInfo(description = "删除商户网址")
    @RequestMapping(value = "/webSite/delete")
    @ResponseBody
    public List<Integer> deleteMerchantWebSite(@RequestBody List<Integer> idList) {
        return merchantService.deleteMerchantWebSite(idList);
    }

    @SystemLogInfo(description = "修改商户网址")
    @RequestMapping(value = "/webSite/update")
    @ResponseBody
    public Boolean updateMerchantWebSite(@RequestBody MerchantWebSite merchantWebSite) {
        return merchantService.updateMerchantWebSite(merchantWebSite, UserInfoUtils.getName());
    }

    @SystemLogInfo(description = "添加产品类型")
    @RequestMapping(value = "/webSite/addProType")
    @ResponseBody
    public Boolean addMerchantWebsiteProType(@RequestBody MerchantWebsiteProType merchantWebsiteProType) {
        return merchantService.addMerchantWebsiteProType(merchantWebsiteProType, UserInfoUtils.getName());
    }

    @SystemLogInfo(description = "删除产品类型")
    @RequestMapping(value = "/webSite/deleteProType")
    @ResponseBody
    public List<Long> deleteMerchantWebsiteProType(@RequestBody List<Long> idList) {
        return merchantService.deleteMerchantWebsiteProType(idList);
    }

    @SystemLogInfo(description = "修改产品类型")
    @RequestMapping(value = "/webSite/updateProType")
    @ResponseBody
    public Boolean updateMerchantWebsiteProType(@RequestBody MerchantWebsiteProType merchantWebsiteProType) {
        return merchantService.updateMerchantWebsiteProType(merchantWebsiteProType, UserInfoUtils.getName());
    }

    @SystemLogInfo(description = "获取产品类型列表")
    @RequestMapping(value = "/webSite/getAllProType")
    @ResponseBody
    public List<MerchantWebsiteProType> getAllMerchantWebsiteProType() {
        return merchantService.selectAllMerchantWebsiteProType();
    }

    @RequestMapping(value = "/quickTest/getInit")
    @ResponseBody
    public Map<String, Object> getQuickTestInit() {
        return merchantService.getQuickTestInit();
    }

    @SystemLogInfo(description = "快捷测试")
    @RequestMapping(value = "/quickTest/test")
    public ModelAndView quickTest(TradeObject tradeObject)  {
        Map<String, Object> params = new HashMap<>();
        String result;
        ModelAndView modelAndView = new ModelAndView();
        switch (tradeObject.getTransType()) {
            case QuickTestUtils.INLINE_PAY:
                params.put("tradeInfo", QuickTestUtils.inlinePay(tradeObject));
                result = HttpClientUtils.doPost(HttpClientUtils.getHttpClient(), tradeObject.getPayURL(), params);
                modelAndView.setViewName("/views/business/quick_test_result");
                modelAndView.addObject("testResult", result);
                break;
            case QuickTestUtils.CROSS_PAY:
                modelAndView.setViewName("/views/business/quick_test_cross_pay_send");
                modelAndView.addObject("tradeInfo", QuickTestUtils.crossPay(tradeObject));
                modelAndView.addObject("payURL", tradeObject.getPayURL());
                break;
            default:
                modelAndView.setViewName("/views/business/quick_test");
                break;
        }
        return modelAndView;
    }

    @ResponseBody
    @RequestMapping(value = "/certificateImg", method = RequestMethod.GET)
    public ResponseEntity<byte[]> getImageAsResource(String certificate) throws IOException {
        File img = new File(globalConfiguration.getFileUploadPath() + certificate);
        if (img.exists()) {
            FileInputStream inputStream = new FileInputStream(img);
            byte[] media = IOUtils.toByteArray(inputStream);
            HttpHeaders headers = new HttpHeaders();
            headers.setCacheControl(CacheControl.noCache().getHeaderValue());
            return new ResponseEntity<>(media, headers, HttpStatus.OK);
        } else {
            return new ResponseEntity<>(null, null, HttpStatus.NOT_FOUND);
        }
    }
}